package lwk.juc.collection;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author:lwk
 * @create: 2022-08-12 22:04
 * @Description: List集合测试
 *
 * List<String> list = new ArrayList<>();<br>
 * 多个线程操作线程不安全的集合时（如ArrayList）,会发生并发修改异常.<br>
 * java.util.ConcurrentModificationException:并发修改异常.<br><br>
 * 解决方案：<br>
 * <pre>
 * 1、List<String> list = new Vector<>();
 * Vector底层方法用synchronized关键字修饰，确保线程安全<br>
 * 2、List<String> list = Collections.synchronizedList(new ArrayList<>())
 * SynchronizedList就是在List的操作外包加了一层synchronize同步控制,
 * 注意使用Iterator遍历时,异步修改list的结构,同样也会发生并法修改异常.
 * 如：{@link SynchronizedTest 使用Iterator遍历时,异步修改list的结构}
 * 参考：简单理解<br>
 * 3、List<String> list = new CopyOnWriteArrayList<>();
 * CopyOnWrite,即COW,计算机程序设计领域的一种优化策略
 * 多个线程调用的时候，读取到的list是固定，修改的时候会先copy一份数据，修改完成之后覆盖原对象引用,由于写操作的开销大，所以多用于读多写少的时候，并且存在读到的数据不是最新的情况。
 * 读写分离
 * </pre>

 *
 * @see <a href="https://blog.csdn.net/u012816626/article/details/111090575">简单理解Collections.synchronizedList</a>
 */

public class ListTest {
    public static void main(String[] args) throws InterruptedException {

        List<String> list = new CopyOnWriteArrayList<>();

        for (int i = 1; i <= 100; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(list);
            }).start();
        }

        Thread.sleep(100);
        new Thread(()-> {
            Iterator<String> iterator = list.iterator();
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
            }
        }).start();
        new Thread(()->{
            list.add(UUID.randomUUID().toString().substring(0,5));
            System.out.println(list);
        }).start();
    }
}
